package com.yixin.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.BusinessException;
import com.yixin.hospital.controller.DrugDepositoryAuthController;
import com.yixin.hospital.controller.PurchaseOrderController;
import com.yixin.hospital.entity.bo.PageInfo;
import com.yixin.hospital.entity.bo.PurchaseOrderDetail;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.drug.DrugAddReqDTO;
import com.yixin.hospital.entity.dto.req.drug.DrugEditReqDTO;
import com.yixin.hospital.entity.dto.req.drug.DrugPicEditReqDTO;
import com.yixin.hospital.entity.dto.req.purchaseorder.PurchaseOrderAddReqDTO;
import com.yixin.hospital.entity.dto.req.visit.VisitSubPackageDrugReqDTO;
import com.yixin.hospital.entity.vo.*;
import com.yixin.hospital.enums.*;
import com.yixin.hospital.mapper.extend.DrugDepositoryDrugExtendMapper;
import com.yixin.hospital.mapper.extend.DrugExtendMapper;
import com.yixin.hospital.service.*;
import com.yixin.hospital.mapper.DrugMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【drug(药品表)】的数据库操作Service实现
* @createDate 2024-07-04 14:18:17
*/
@Service
@Slf4j
public class DrugServiceImpl extends ServiceImpl<DrugMapper, Drug>
    implements DrugService{

    @Resource
    DrugPicService drugPicService;
    @Resource
    DrugTypeService drugTypeService;
    @Resource
    DrugDepositoryDrugService drugDepositoryDrugService;
    @Resource
    private DrugDepositoryDrugExtendMapper drugDepositoryDrugExtendMapper;
    @Resource
    DrugExtendMapper drugExtendMapper;
    @Resource
    DrugDeptService drugDeptService;
    @Resource
    DrugDepositoryService drugDepositoryService;

    @Value("${drug.near.expiration.sec}")
    private int drugNearExpiration;

    @Resource
    PurchaseOrderController purchaseOrderController;
    @Resource
    DrugDepositoryAuthController drugDepositoryAuthController;
    @Autowired
    private VisitSubPackageDrugService visitSubPackageDrugService;
    @Autowired
    private VisitPackageDrugService visitPackageDrugService;
    @Autowired
    private GuidanceService guidanceService;
    @Autowired
    private VisitInspectionListService visitInspectionListService;

    @Override
    public ApiResult<PageInfo<DrugVo>> allList(int currentPage, int pageSize, Long firstType, Long secondType, Long thirdType, String pinyinCode) {
        IPage<DrugVo> page = drugExtendMapper.pageVo(Page.of(currentPage, pageSize), firstType, secondType, thirdType, pinyinCode);
        List<DrugVo> list = page.getRecords();
        List<DrugVo> resp = new ArrayList<>();
        for (DrugVo drugVo : list) {
            if (Strings.isNotBlank(drugVo.getSellJobDuty())) {
                String[] split = drugVo.getSellJobDuty().split(",");
                drugVo.setSellJobDutyList(Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList()));
            }
            if (Strings.isNotBlank(drugVo.getTag())) {
                String[] split = drugVo.getTag().split(",");
                drugVo.setTagList(Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList()));
            }
            // 药品负责部门
//            LambdaQueryWrapper<DrugDept> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.eq(DrugDept::getDrugId, drugVo.getId());
//            List<DrugDept> list1 = drugDeptService.list(new LambdaQueryWrapper<>());
//            List<Long> collect = list1.stream().map(DrugDept::getDeptId).collect(Collectors.toList());
//            drugVo.setDrugDeptIds(collect);
            resp.add(drugVo);
        }

        PageInfo<DrugVo> drugVoPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(page, drugVoPageInfo);
        drugVoPageInfo.setRecords(resp);
        return ApiResult.success(drugVoPageInfo);
    }

    @Override
    public ApiResult<String> getDrugCode(int firstType, int secondType, int thirdType) {
        String code;
        String firstTypeAbb = drugTypeService.getById(firstType).getAbb();
        String secondTypeAbb = drugTypeService.getById(secondType).getAbb();
        String thirdTypeAbb = drugTypeService.getById(thirdType).getAbb();
        String allType = firstTypeAbb + secondTypeAbb + thirdTypeAbb;
        LambdaQueryWrapper<Drug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Drug::getId);
        queryWrapper.last("limit 1");
        Drug drugDb = this.getOne(queryWrapper);
        if (drugDb == null) {
            code = allType + "000001";
        } else {
            String codeInt = drugDb.getCode().substring(3);
            int maxCode = Integer.parseInt(codeInt) + 1;
            code = allType + String.format("%06d", maxCode);
        }
        return ApiResult.success(code);
    }

    @Override
    public ApiResult<?> add(DrugAddReqDTO drugAddReqDTO, String userName) {
        Drug drug = new Drug();
        BeanUtils.copyProperties(drugAddReqDTO, drug);
        String code;
        String firstTypeAbb = drugTypeService.getById(drugAddReqDTO.getFirstType()).getAbb();
        String secondTypeAbb = drugTypeService.getById(drugAddReqDTO.getSecondType()).getAbb();
        String thirdTypeAbb = drugTypeService.getById(drugAddReqDTO.getThirdType()).getAbb();
        String allType = firstTypeAbb + secondTypeAbb + thirdTypeAbb;
        LambdaQueryWrapper<Drug> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Drug::getId);
        queryWrapper.last("limit 1");
        Drug drugDb = this.getOne(queryWrapper);
        if (drugDb == null) {
            code = allType + "000001";
        } else {
            String codeInt = drugDb.getCode().substring(3);
            int maxCode = Integer.parseInt(codeInt) + 1;
            code = allType + String.format("%06d", maxCode);
        }
        drug.setCode(code);
        drug.setStatus(DrugStatusEnum.ON.getCode());
        if (!CollectionUtils.isEmpty(drugAddReqDTO.getSellJobDutyList())) {
            drug.setSellJobDuty(StringUtils.join(drugAddReqDTO.getSellJobDutyList(), ","));
        }
        if (!CollectionUtils.isEmpty(drugAddReqDTO.getTag())) {
            drug.setTag(StringUtils.join(drugAddReqDTO.getTag(), ","));
        }
        drug.setCreatedBy(userName);
        drug.setUpdatedBy(userName);
        this.save(drug);
        if (!drugAddReqDTO.getDrugDeptIds().isEmpty()) {
            List<DrugDept> drugDeptList = new ArrayList<>();
            for (Long drugDeptId : drugAddReqDTO.getDrugDeptIds()) {
                DrugDept drugDept = new DrugDept();
                drugDept.setDrugId(drug.getId());
                drugDept.setDeptId(drugDeptId);
                drugDept.setCreatedBy(userName);
                drugDept.setUpdatedBy(userName);
                drugDeptList.add(drugDept);
            }
            drugDeptService.saveBatch(drugDeptList);
        }
        if (StringUtils.isNotBlank(drugAddReqDTO.getPic())) {
            DrugPic drugPic = new DrugPic();
            drugPic.setDrugId(drug.getId());
            drugPic.setPicture(drugAddReqDTO.getPic());
            drugPic.setUpdatedBy(userName);
            drugPic.setCreatedBy(userName);
            drugPicService.save(drugPic);
        }
        return ApiResult.success();
    }

    @Override
    public ApiResult<?> edit(DrugEditReqDTO drugEditReqDTO, String userName) {
        Drug drug = new Drug();
        BeanUtils.copyProperties(drugEditReqDTO, drug, "code");
        String firstTypeAbb = drugTypeService.getById(drugEditReqDTO.getFirstType()).getAbb();
        String secondTypeAbb = drugTypeService.getById(drugEditReqDTO.getSecondType()).getAbb();
        String thirdTypeAbb = drugTypeService.getById(drugEditReqDTO.getThirdType()).getAbb();
        String allType = firstTypeAbb + secondTypeAbb + thirdTypeAbb;
        if (!CollectionUtils.isEmpty(drugEditReqDTO.getSellJobDutyList())) {
            drug.setSellJobDuty(StringUtils.join(drugEditReqDTO.getSellJobDutyList(), ","));
        }
        if (!CollectionUtils.isEmpty(drugEditReqDTO.getTag())) {
            drug.setTag(StringUtils.join(drugEditReqDTO.getTag(), ","));
        }
        drug.setUpdatedBy(userName);
        this.updateById(drug);

        if (!drugEditReqDTO.getDrugDeptIds().isEmpty()) {
            drugDeptService.remove(new LambdaQueryWrapper<DrugDept>().eq(DrugDept::getDrugId, drugEditReqDTO.getId()));
            List<DrugDept> drugDeptList = new ArrayList<>();
            for (Long drugDeptId : drugEditReqDTO.getDrugDeptIds()) {
                DrugDept drugDept = new DrugDept();
                drugDept.setDrugId(drug.getId());
                drugDept.setDeptId(drugDeptId);
                drugDept.setCreatedBy(userName);
                drugDept.setUpdatedBy(userName);
                drugDeptList.add(drugDept);
            }
            drugDeptService.saveBatch(drugDeptList);
        }
        if (StringUtils.isNotBlank(drugEditReqDTO.getPic())) {
            drugPicService.remove(new LambdaQueryWrapper<DrugPic>().eq(DrugPic::getDrugId, drugEditReqDTO.getId()));
            DrugPic drugPic = new DrugPic();
            drugPic.setDrugId(drug.getId());
            drugPic.setPicture(drugEditReqDTO.getPic());
            drugPic.setUpdatedBy(userName);
            drugPic.setCreatedBy(userName);
            drugPicService.save(drugPic);
        }
        return ApiResult.success();
    }

    @Override
    public ApiResult editDrugPic(DrugPicEditReqDTO drugPicEditReqDTO, String userName) {
        DrugPic drugPic = new DrugPic();
        drugPic.setDrugId(drugPicEditReqDTO.getId());
        drugPic.setPicture(drugPicEditReqDTO.getPic());
        BeanUtils.copyProperties(drugPicEditReqDTO, drugPic);
        drugPic.setCreatedBy(userName);
        drugPic.setUpdatedBy(userName);
        LambdaUpdateWrapper<DrugPic> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(DrugPic::getDrugId, drugPicEditReqDTO.getId());
        drugPicService.saveOrUpdate(drugPic, updateWrapper);
        return ApiResult.success();
    }

    @Override
    public ApiResult queryPicById(Long id) {
        LambdaQueryWrapper<DrugPic> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(DrugPic::getDrugId, id);
        List<DrugPic> list = drugPicService.list(queryWrapper);
        return ApiResult.success(CollectionUtils.isEmpty(list)?"":list.get(0));
    }

    @Override
    public ApiResult<List<DrugVo>> queryByPinyinCode(String pinyinCode) {
        IPage<DrugVo> page = drugExtendMapper.pageVo(Page.of(1, 50), null, null, null, pinyinCode);
        return ApiResult.success(page.getRecords());
    }

    @Override
    public ApiResult<List<DrugVo>> queryByCodeAndOptType(String pinyinCode, Integer optType, HttpServletRequest request) {
        ApiResult<List<Long>> depositoryIdListByAuth = drugDepositoryAuthController.getDepositoryIdListByAuth(optType, request);
        List<DrugVo> response = drugExtendMapper.pageVoByDrugDepository(pinyinCode, depositoryIdListByAuth.getData());
        return ApiResult.success(response);
    }

    @Override
    public ApiResult<List<DrugVo>> queryByPinyinCodeAndDepository(String pinyinCode, List<Long> depositoryIds, Integer type) {
        List<DrugType> list = drugTypeService.list(new LambdaQueryWrapper<DrugType>().eq(DrugType::getPid, 0));
        List<Long> firstTypeIdList = list.stream().filter(drugType -> !Arrays.asList("J" , "Z").contains(drugType.getAbb())).map(DrugType::getId).collect(Collectors.toList());
        Integer sellMethod = null;
        if (Objects.nonNull(type)) {
            if (VisitTypeEnum.INSPECTION.getCode().equals(type)) {
                firstTypeIdList = list.stream().filter(drugType -> Arrays.asList("J").contains(drugType.getAbb())).map(DrugType::getId).collect(Collectors.toList());
            } else if (VisitTypeEnum.SUB_PACKAGE_DRUG.getCode().equals(type)) {
                sellMethod = DrugSellMethodEnum.SUB_PACKAGE.getCode();
            } else if (VisitTypeEnum.PACKAGE_DRUG.getCode().equals(type)) {
                sellMethod = DrugSellMethodEnum.PACKAGE.getCode();
            }
        }
        log.info("firstTypeIdList: {}", firstTypeIdList);
        IPage<DrugVo> page = drugExtendMapper.pageVoProductTime(Page.of(1, 50), pinyinCode, depositoryIds, firstTypeIdList, sellMethod);
        for (DrugVo record : page.getRecords()) {
            // 外包装数量（x盒） * 内包装数量（y片/盒）
            record.setInnerUnitNum(record.getNum() * record.getInnerNum());
        }
        return ApiResult.success(page.getRecords());
    }

    @Override
    public ApiResult<DrugDepositoryDrugVo> queryByCodeDepositoryId(String drugCode, Long depositoryId) {
        DrugDepositoryDrugVo drugDepositoryDrugVo = drugDepositoryDrugExtendMapper.countDepository(depositoryId, drugCode);
        return ApiResult.success(drugDepositoryDrugVo);
    }

    @Override
    public ApiResult<IPage<DrugDepositoryDrugVo>> depositoryNumList(int currentPage, int pageSize, String drugName, Long drugDepositoryId, Long userId) {
        if (!drugDepositoryAuthController.checkDrugDepositoryAuth(userId, drugDepositoryId, DrugDepositoryOtpTypeEnum.QUERY.getCode())) {
            return ApiResult.error(ResponseCodeEnum.AUTH_NOT_FOUND);
        }
        IPage<DrugDepositoryDrugVo> drugDepositoryDrugVoList = drugDepositoryDrugExtendMapper.DepositoryCountListPage(Page.of(currentPage, pageSize), Arrays.asList(drugDepositoryId), drugName, 0);
        for (DrugDepositoryDrugVo record : drugDepositoryDrugVoList.getRecords()) {
            if (Objects.isNull(record.getExpiration())) continue;
            long daysDiff = ChronoUnit.DAYS.between(record.getExpiration().toInstant(), new Date().toInstant());
            if (daysDiff > drugNearExpiration) {
                record.setNearExpiration(true);
            }
        }
        return ApiResult.success(drugDepositoryDrugVoList);
    }

    @Override
    public ApiResult<List<DrugDepositoryDrugVo>> depositoryNumDetail(String drugCode, Long drugDepositoryId) {
        List<DrugDepositoryDrugVo> drugDepositoryDrugVoList = drugDepositoryDrugExtendMapper.DepositoryCountList(Arrays.asList(drugDepositoryId), drugCode);
        return ApiResult.success(drugDepositoryDrugVoList);
    }

    @Override
    public ApiResult<PurchaseOrderVO> queryDepositoryAllNum(HttpServletRequest request) {
        List<DrugDepositoryDrugVo> drugDepositoryDrugVoList = drugDepositoryDrugExtendMapper.depositoryCountAllList(null);
        Map<String, DrugDepositoryAllDrugVo> drugCodeMap = new HashMap<>();
        for (DrugDepositoryDrugVo drugDepositoryDrugVo : drugDepositoryDrugVoList) {
            DrugDepositoryAllDrugVo resVo = drugCodeMap.get(drugDepositoryDrugVo.getDrugCode());
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            BeanUtils.copyProperties(drugDepositoryDrugVo, drugDepositoryVo);
            drugDepositoryVo.setId(drugDepositoryDrugVo.getDepositoryId());
            drugDepositoryVo.setName(drugDepositoryDrugVo.getDepositoryName());
            // is exist
            if (Objects.nonNull(resVo)) {
                resVo.getDrugDepositoryVoList().add(drugDepositoryVo);
            } else {
                // drug info
                DrugDepositoryAllDrugVo drugDepositoryAllDrugVo = new DrugDepositoryAllDrugVo();
                BeanUtils.copyProperties(drugDepositoryDrugVo, drugDepositoryAllDrugVo);
                drugDepositoryAllDrugVo.setDepositoryId(drugDepositoryDrugVo.getDepositoryId());
                drugDepositoryAllDrugVo.setDepositoryName(drugDepositoryDrugVo.getDepositoryName());
//                drugDepositoryAllDrugVo.setSourceNum(drugDepositoryDrugVo.getInventory());
                if (Objects.nonNull(drugDepositoryDrugVo.getDepositoryId())) {  // 有库存 才添加
                    drugDepositoryAllDrugVo.getDrugDepositoryVoList().add(drugDepositoryVo);
                }
                drugCodeMap.put(drugDepositoryAllDrugVo.getDrugCode(), drugDepositoryAllDrugVo);
                // repository info
//                DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
//                BeanUtils.copyProperties(drugDepositoryDrugVo, drugDepositoryVo);
//                drugDepositoryVo.setId(drugDepositoryDrugVo.getDrugDepositoryId());
//                drugDepositoryVo.setName(drugDepositoryDrugVo.getDepositoryName());
//                drugDepositoryVo.setInventory(Objects.isNull(drugDepositoryDrugVo.getInventory()) ? 0 : drugDepositoryDrugVo.getInventory());
//                drugDepositoryVo.setSubInventory(Objects.isNull(drugDepositoryDrugVo.getSubInventory()) ? 0 : drugDepositoryDrugVo.getSubInventory());
//                drugDepositoryVo.setDoneInventory(Objects.isNull(drugDepositoryDrugVo.getDoneInventory()) ? 0 : drugDepositoryDrugVo.getDoneInventory());
//                drugDepositoryVo.setDoneSubInventory(Objects.isNull(drugDepositoryDrugVo.getDoneSubInventory()) ? 0 : drugDepositoryDrugVo.getDoneSubInventory());
//                drugDepositoryAllDrugVo.getDrugDepositoryVoList().add(drugDepositoryVo);
            }
        }
        // 药品维度得列表，每个药品添加各个库
        List<DrugDepositoryAllDrugVo> drugResponse = new ArrayList<>();
        Map<Long, DrugDepository> allDrugDepository = drugDepositoryService.list().stream().collect(Collectors.toMap(DrugDepository::getId, Function.identity()));
        List<PurchaseOrderDetail> initPurchaseOrderList = new ArrayList<>();
        for (Map.Entry<String, DrugDepositoryAllDrugVo> entry : drugCodeMap.entrySet()) {
            DrugDepositoryAllDrugVo value = entry.getValue();
            List<Long> existDepositoryId = value.getDrugDepositoryVoList().stream().map(DrugDepositoryVo::getId).collect(Collectors.toList());
            PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
            BeanUtils.copyProperties(value, purchaseOrderDetail);
            purchaseOrderDetail.setDrugCode(value.getDrugCode());
            purchaseOrderDetail.setSourceNum(Objects.nonNull(existDepositoryId) && Objects.nonNull(value.getDepositoryId()) && existDepositoryId.contains(value.getDepositoryId()) ? value.getInventory() : 0);
            purchaseOrderDetail.setDoneInventory(purchaseOrderDetail.getSourceNum());
            purchaseOrderDetail.setDepositoryId(value.getDepositoryId());
            purchaseOrderDetail.setDepositoryName(value.getDepositoryName());
            initPurchaseOrderList.add(purchaseOrderDetail);
            for (Long depositoryId : allDrugDepository.keySet()) {
                if (existDepositoryId.contains(depositoryId)) continue;
                DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
                drugDepositoryVo.setId(depositoryId);
                drugDepositoryVo.setName(allDrugDepository.get(depositoryId).getName());
                drugDepositoryVo.setIsTop(allDrugDepository.get(depositoryId).getIsTop());
                drugDepositoryVo.setInventory(0);
                drugDepositoryVo.setSourceNum(0);
                drugDepositoryVo.setDoneInventory(0);
                drugDepositoryVo.setSubInventory(0);
                drugDepositoryVo.setDoneSubInventory(0);
                value.getDrugDepositoryVoList().add(drugDepositoryVo);
            }
            value.getDrugDepositoryVoList().sort(Comparator.comparing(DrugDepositoryVo::getId));
            drugResponse.add(value);
        }
        PurchaseOrderAddReqDTO initPurchaseOrderAddReqDTO = new PurchaseOrderAddReqDTO();
        initPurchaseOrderAddReqDTO.setSupplier(1L);
        initPurchaseOrderAddReqDTO.setType("集中");
        initPurchaseOrderAddReqDTO.setStatus(0);
        initPurchaseOrderAddReqDTO.setPurchaseOrderDrugList(initPurchaseOrderList);
        ApiResult<?> addResp = purchaseOrderController.add(initPurchaseOrderAddReqDTO, request);
        if (Objects.isNull(addResp.getData())) {
            return ApiResult.success();
        }
        PurchaseOrder purchaseOrder = (PurchaseOrder) addResp.getData();
        PurchaseOrderVO purchaseOrderVO = new PurchaseOrderVO();
        BeanUtils.copyProperties(purchaseOrder, purchaseOrderVO);
        purchaseOrderVO.setPurchaseOrderDrugList(drugResponse);
        return ApiResult.success(purchaseOrderVO);
    }

    @Override
    public ApiResult<DrugDepositoryAllDrugVo> queryDepositoryNum(String drugCode, HttpServletRequest request) {
        List<DrugDepositoryDrugVo> drugDepositoryDrugVoList = drugDepositoryDrugExtendMapper.depositoryCountAllList(drugCode);
        DrugDepositoryAllDrugVo drugDepositoryAllDrugVo = new DrugDepositoryAllDrugVo();
        for (DrugDepositoryDrugVo drugDepositoryDrugVo : drugDepositoryDrugVoList) {
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            BeanUtils.copyProperties(drugDepositoryDrugVo, drugDepositoryVo);
            drugDepositoryVo.setId(drugDepositoryDrugVo.getDepositoryId());
            drugDepositoryVo.setName(drugDepositoryDrugVo.getDepositoryName());
            // drug info
            BeanUtils.copyProperties(drugDepositoryDrugVo, drugDepositoryAllDrugVo);
            drugDepositoryAllDrugVo.setDepositoryId(drugDepositoryDrugVo.getDepositoryId());
            drugDepositoryAllDrugVo.setDepositoryName(drugDepositoryDrugVo.getDepositoryName());
//                drugDepositoryAllDrugVo.setSourceNum(drugDepositoryDrugVo.getInventory());
            if (Objects.nonNull(drugDepositoryDrugVo.getDepositoryId())) {  // 有库存 才添加
                drugDepositoryAllDrugVo.getDrugDepositoryVoList().add(drugDepositoryVo);
            }
        }
        // 药品维度得列表，每个药品添加各个库
        Map<Long, DrugDepository> allDrugDepository = drugDepositoryService.list().stream().collect(Collectors.toMap(DrugDepository::getId, Function.identity()));
        List<PurchaseOrderDetail> initPurchaseOrderList = new ArrayList<>();
        List<Long> existDepositoryId = drugDepositoryAllDrugVo.getDrugDepositoryVoList().stream().map(DrugDepositoryVo::getId).collect(Collectors.toList());
        PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
        BeanUtils.copyProperties(drugDepositoryAllDrugVo, purchaseOrderDetail);
        purchaseOrderDetail.setDrugCode(drugDepositoryAllDrugVo.getDrugCode());
        purchaseOrderDetail.setSourceNum(Objects.nonNull(existDepositoryId) && Objects.nonNull(drugDepositoryAllDrugVo.getDepositoryId()) && existDepositoryId.contains(drugDepositoryAllDrugVo.getDepositoryId()) ? drugDepositoryAllDrugVo.getInventory() : 0);
        purchaseOrderDetail.setDoneInventory(purchaseOrderDetail.getSourceNum());
        purchaseOrderDetail.setDepositoryId(drugDepositoryAllDrugVo.getDepositoryId());
        purchaseOrderDetail.setDepositoryName(drugDepositoryAllDrugVo.getDepositoryName());
        initPurchaseOrderList.add(purchaseOrderDetail);
        for (Long depositoryId : allDrugDepository.keySet()) {
            if (existDepositoryId.contains(depositoryId)) continue;
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            drugDepositoryVo.setId(depositoryId);
            drugDepositoryVo.setName(allDrugDepository.get(depositoryId).getName());
            drugDepositoryVo.setIsTop(allDrugDepository.get(depositoryId).getIsTop());
            drugDepositoryVo.setInventory(0);
            drugDepositoryVo.setSourceNum(0);
            drugDepositoryVo.setDoneInventory(0);
            drugDepositoryVo.setSubInventory(0);
            drugDepositoryVo.setDoneSubInventory(0);
            drugDepositoryAllDrugVo.getDrugDepositoryVoList().add(drugDepositoryVo);
        }
        drugDepositoryAllDrugVo.getDrugDepositoryVoList().sort(Comparator.comparing(DrugDepositoryVo::getId));

        return ApiResult.success(drugDepositoryAllDrugVo);
    }

    @Override
    public ApiResult<?> takeDrug(VisitSubPackageDrugReqDTO visitSubPackageDrugReqDTO, String userName) {
        String guidanceCode = visitSubPackageDrugReqDTO.getGuidanceCode();
        Guidance guidance = guidanceService.getOne(new LambdaQueryWrapper<Guidance>().eq(Guidance::getGuidanceCode, guidanceCode));
        if (!guidance.getStatus().equals(GuidanceStatusEnum.DRUG.getCode()) && !guidance.getStatus().equals(GuidanceStatusEnum.CHECKING_DRUG.getCode())) throw new BusinessException(ResponseCodeEnum.TACK_DRUG_EXIST.getMsg());
        // 分装
        List<VisitSubPackageDrug> visitSubPackageDrugList = visitSubPackageDrugService.list(new LambdaQueryWrapper<VisitSubPackageDrug>().eq(VisitSubPackageDrug::getGuidanceCode, guidanceCode));
        // 检查入参开药数量与查询的数量是否相等
        long count = visitSubPackageDrugList.stream().filter(subDrug -> subDrug.getStatus().equals(DrugVisitStatusEnum.PAID.getCode())).count();
        long reqCount = visitSubPackageDrugReqDTO.getVisitSubPackageDrugList().stream().filter(subDrug -> subDrug.getStatus().equals(DrugVisitStatusEnum.PAID.getCode())).count();
        if (count != reqCount) {
            throw new BusinessException(ResponseCodeEnum.INTERNAL_SERVER_ERROR.getMsg());
        }
        if (!CollectionUtils.isEmpty(visitSubPackageDrugList)) {
            for (VisitSubPackageDrug visitSubPackageDrug : visitSubPackageDrugList) {
                if (DrugVisitStatusEnum.PENDING.getCode() == visitSubPackageDrug.getStatus()) throw new BusinessException(ResponseCodeEnum.TAKE_DRUG_ERROR.getMsg());
                visitSubPackageDrug.setStatus(DrugVisitStatusEnum.DONE.getCode());
                visitSubPackageDrug.setUpdatedBy(userName);
                visitSubPackageDrug.setUpdatedTime(new Date());
            }
            // 更新状态（减库存在开处方时已减）
            visitSubPackageDrugService.updateBatchById(visitSubPackageDrugList);
        }

        // 整装
        List<VisitPackageDrug> visitPackageDrugList = visitPackageDrugService.list(new LambdaQueryWrapper<VisitPackageDrug>().eq(VisitPackageDrug::getGuidanceCode, guidanceCode));
        // 检查入参开药数量与查询的数量是否相等
        long packageCount = visitPackageDrugList.stream().filter(subDrug -> subDrug.getStatus().equals(DrugVisitStatusEnum.PAID.getCode())).count();
        long reqPackageCount = visitSubPackageDrugReqDTO.getVisitPackageDrugList().stream().filter(subDrug -> subDrug.getStatus().equals(DrugVisitStatusEnum.PAID.getCode())).count();
        if (packageCount != reqPackageCount) {
            throw new BusinessException(ResponseCodeEnum.INTERNAL_SERVER_ERROR.getMsg());
        }
        if (!CollectionUtils.isEmpty(visitPackageDrugList)) {
            for (VisitPackageDrug visitPackageDrug : visitPackageDrugList) {
                if (DrugVisitStatusEnum.PENDING.getCode() == visitPackageDrug.getStatus()) throw new BusinessException(ResponseCodeEnum.TAKE_DRUG_ERROR.getMsg());
                visitPackageDrug.setStatus(DrugVisitStatusEnum.DONE.getCode());
                visitPackageDrug.setUpdatedBy(userName);
                visitPackageDrug.setUpdatedTime(new Date());
            }
            // 更新状态（减库存在开处方时已减）
            visitPackageDrugService.updateBatchById(visitPackageDrugList);
        }
        guidance.setStatus(GuidanceStatusEnum.DONE.getCode());
        long inspectionCount = visitInspectionListService.count(new LambdaQueryWrapper<VisitInspectionList>().eq(VisitInspectionList::getGuidanceCode, guidanceCode).eq(VisitInspectionList::getStatus, DrugVisitStatusEnum.PAID.getCode()));
        if (inspectionCount != 0) {
            guidance.setStatus(GuidanceStatusEnum.CHECKING.getCode());
        }
        guidance.setUpdatedBy(userName);
        guidance.setUpdatedTime(new Date());
        guidanceService.updateById(guidance);
        return ApiResult.success();
    }
}




